package com.mcxx.modules.temporary.fundpay.service.read;

import cn.hutool.core.date.DateUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.DictConstant;
import com.mcxx.modules.base.service.read.DictionaryReadService;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.miniSalvation.fundpay.dto.FundPayDTO;
import com.mcxx.modules.miniSalvation.fundpay.dto.FundPayExcelDto;
import com.mcxx.modules.miniSalvation.fundpay.dto.TempFundPayExcelDto;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayEntity;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayStatusEntity;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayParam;
import com.mcxx.modules.temporary.fundpay.dao.read.TmpFundPayMemberReadDao;
import com.mcxx.modules.temporary.fundpay.dao.read.TmpFundPayReadDao;
import com.mcxx.modules.temporary.fundpay.dto.TmpFundPayDTO;
import com.mcxx.modules.temporary.fundpay.dto.TmpFundPayFamilyDTO;
import com.mcxx.modules.temporary.fundpay.entity.TmpFundPayEntity;
import com.mcxx.modules.temporary.fundpay.param.TmpFundPayParam;
import com.mcxx.result.BaseResult;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.restservice.requestbean.PageParam;
import com.yinhai.ta404.core.restservice.resultbean.Page;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import com.yinhai.ta404.module.dict.entity.TaDictPo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@TaTransactional(readOnly = true)
public class TmpFundPayReadService {

    @Autowired
    private TmpFundPayReadDao tmpFundPayReadDao;
    @Autowired
    private TmpFundPayMemberReadDao tmpFundPayMemberReadDao;
    @Autowired
    private DictionaryReadService dictionaryReadService;


    public BaseResult<Boolean> verifyFunPay( String areaCode, String rescueyears,String payWay) {
        BaseResult<Boolean> resultMessage = new BaseResult<>();
        Boolean b2 = tmpFundPayReadDao.isExistsFundPay(rescueyears,areaCode,payWay) > 0;
        if (b2) {
            throw new BizException(FailureCode.ERR_10011);
        }
        return resultMessage;
    }


    public Page getFundPayList(TmpFundPayParam param, PageParam pageParam, UserAccountVo accountVo){

        QueryParamUtil.setBaseParamValue(param, accountVo);


        tmpFundPayReadDao.beginPager(pageParam);
        List<TmpFundPayEntity> fundPayEntityList = tmpFundPayReadDao.listByCondition(param);


        return tmpFundPayReadDao.endPager(fundPayEntityList);
    }


    public List<TmpFundPayDTO> getFundPayList(TmpFundPayParam param, UserAccountVo accountVo){
        List<TmpFundPayEntity> fundPayEntityList = tmpFundPayReadDao.listByCondition(param);
        List<TmpFundPayDTO>  tmpFundPayDTOList = new ArrayList<>();
        for (TmpFundPayEntity fundPayEntity :fundPayEntityList) {
            TmpFundPayDTO dto = new TmpFundPayDTO();
            BeanUtils.copyProperties(fundPayEntity, dto);
            tmpFundPayDTOList.add(dto);
        }
        return tmpFundPayDTOList;
    }


    public List<TmpFundPayEntity> getFundPayList(TmpFundPayParam param){
        return tmpFundPayReadDao.listByCondition(param);
    }


    public TmpFundPayEntity getById(String fundPayId){
        return tmpFundPayReadDao.getById(fundPayId);
    }


    public String getFundName(String payWay, String areaCode){
        Date beginOfMonth = DateUtil.beginOfMonth(new Date());
        int fundNum = tmpFundPayReadDao.getFundPayNum(payWay, areaCode,
                DateUtil.format(beginOfMonth, "yyyy-MM-dd"), null);
        TaDictPo taDictPo = dictionaryReadService.getCodeCache(DictConstant.PAYMENT_MANNER, payWay);
        String fundName = DateUtil.format(beginOfMonth, "yyyy年MM月") + "第" +  (fundNum + 1) + "批" + taDictPo.getLabel() + "发放名册";
        return fundName;
    }

    public int getFundPayNum(Date payDate, String areaCode, String payWay, String status){
        Date beginOfMonth = DateUtil.beginOfMonth(payDate);
        return tmpFundPayReadDao.getFundPayNum(payWay, areaCode,
                DateUtil.format(beginOfMonth, "yyyy-MM-dd"), status);
    }


    public TmpFundPayEntity isCanOperate(String fundPayId, List<String> stateList){
        TmpFundPayEntity fundPayEntity = tmpFundPayReadDao.getById(fundPayId);
        if(!stateList.contains(fundPayEntity.getStatus())){
            TaDictPo taDictPo = dictionaryReadService.getCodeCache(DictConstant.FUND_PAY_STATE, fundPayEntity.getStatus());
            throw new BizException("-1", "当前名册状态为[" + taDictPo.getLabel() + "]无法执行此操作");
        }
        return fundPayEntity;
    }


    public Map<String, String> getTmpFundPayCount(TmpFundPayParam fundPayParam, UserAccountVo userAccountVo){

        QueryParamUtil.setBaseParamValue(fundPayParam, userAccountVo);
        return  tmpFundPayReadDao.getTmpFundPayCount(fundPayParam);
    }


    public Page getTmpFundPayDetail(TmpFundPayParam fundPayParam, PageParam pageParam, UserAccountVo userAccountVo){

        QueryParamUtil.setBaseParamValue(fundPayParam, userAccountVo);

        tmpFundPayMemberReadDao.beginPager(pageParam);
        List<TmpFundPayFamilyDTO>  list = tmpFundPayMemberReadDao.getTmpFundPayDetail(fundPayParam);
        return tmpFundPayMemberReadDao.endPager(list);
    }

    public List<TmpFundPayFamilyDTO> getTmpFundPayDetail(TmpFundPayParam fundPayParam, UserAccountVo userAccountVo){

        QueryParamUtil.setBaseParamValue(fundPayParam, userAccountVo);
        return tmpFundPayMemberReadDao.getTmpFundPayDetail(fundPayParam);
    }


    public Map<String, List<String>> getIdByIdAndStates(List<String> fundPayIdList, List<String> stateList){
        Map<String, List<String>> rstMap = new HashMap<>();

        List<String> canDelIdList = tmpFundPayReadDao.getIdByIdsAndStates(fundPayIdList, stateList);
        if(canDelIdList.size() == fundPayIdList.size()){

            rstMap.put("success", canDelIdList);
            return rstMap;
        }
        if(canDelIdList.size() == 0){

            rstMap.put("fail", fundPayIdList);
            return rstMap;
        }

        List<String> canNotDelIdList = fundPayIdList.stream().filter(id -> canDelIdList.contains(id) == false).collect(Collectors.toList());
        rstMap.put("success", canDelIdList);
        rstMap.put("fail", canNotDelIdList);
        return rstMap;
    }


    public Map<String, List<String>> getIdByIdAndState(List<String> fundPayIdList, String state){
        Map<String, List<String>> rstMap = new HashMap<>();

        List<String> successIdList = tmpFundPayReadDao.getIdByIdsAndState(fundPayIdList, state);
        if(successIdList.size() == fundPayIdList.size()){

            rstMap.put("success", successIdList);
            return rstMap;
        }
        if(successIdList.size() == 0){

            rstMap.put("fail", fundPayIdList);
            return rstMap;
        }

        List<String> failIdList = fundPayIdList.stream().filter(id -> successIdList.contains(id) == false).collect(Collectors.toList());
        rstMap.put("success", successIdList);
        rstMap.put("fail", failIdList);
        return rstMap;
    }

    public List<TmpFundPayEntity> getTmpFundPayByMonth(String validAreaCode, String month){
        return tmpFundPayReadDao.getTmpFundPayByMonth(validAreaCode, month);
    }

    public List<FundPayStatusEntity> getTmpFundpayCreate(String areaCode, String month, String preMonth){
        return tmpFundPayReadDao.getTmpFundpayCreate(areaCode, month, preMonth);
    }

    public String cntFundPay(FundPayDTO fundPayDTO){
        return tmpFundPayReadDao.cntFundPay(fundPayDTO);
    }

    public List<TempFundPayExcelDto> exportExcelTempFundPay(FundPayParam param) {
        return tmpFundPayReadDao.exportExcelTempFundPay(param);
    }

    public List<FundPayStatusEntity> getTmpFundPayCreateInfo(String areaCode, String payDate){
        return tmpFundPayReadDao.getTmpFundPayCreateInfo(areaCode, payDate);
    }
}
